<p>This is essentially Trilium sources + node modules + node.js runtime packaged
  into one 7z file.</p>
<h2>Steps</h2>
<ul>
  <li>SSH into your server</li>
  <li>use <code>wget</code> (or <code>curl</code>) to download latest <code>TriliumNotes-Server-[VERSION]-linux-x64.tar.xz</code> (copy
    link from <a href="https://github.com/TriliumNext/Trilium/releases">release page</a>,
    notice <code>-Server</code> suffix) on your server.</li>
  <li>unpack the archive, e.g. using <code>tar -xf -d TriliumNotes-Server-[VERSION]-linux-x64.tar.xz</code>
  </li>
  <li><code>cd trilium-linux-x64-server</code>
  </li>
  <li><code>./trilium.sh</code>
  </li>
  <li>you can open the browser and open http://[your-server-hostname]:8080 and
    you should see Trilium initialization page</li>
</ul>
<p>The problem with above steps is that once you close the SSH connection,
  the Trilium process is terminated. To avoid that, you have two options:</p>
<ul>
  <li>Kill it (with e.g. <kbd>Ctrl</kbd> + <kbd>C</kbd>) and run again like this: <code>nohup ./trilium.sh &amp;</code>.
    (nohup keeps the process running in the background, <code>&amp;</code> runs
    it in the background)</li>
  <li>Configure systemd to automatically run Trilium in the background on every
    boot</li>
</ul>
<h2>Configure Trilium to auto-run on boot with systemd</h2>
<ul>
  <li>After downloading, extract and move Trilium:</li>
</ul><pre><code class="language-text-x-trilium-auto">tar -xvf TriliumNotes-Server-[VERSION]-linux-x64.tar.xz
sudo mv trilium-linux-x64-server /opt/trilium</code></pre>
<ul>
  <li>Create the service:</li>
</ul><pre><code class="language-text-x-trilium-auto">sudo nano /etc/systemd/system/trilium.service</code></pre>
<ul>
  <li>Paste this into the file (replace the user and group as needed):</li>
</ul><pre><code class="language-text-x-trilium-auto">[Unit]
Description=Trilium Daemon
After=syslog.target network.target

[Service]
User=xxx
Group=xxx
Type=simple
ExecStart=/opt/trilium/trilium.sh
WorkingDirectory=/opt/trilium/

TimeoutStopSec=20
# KillMode=process leads to error, according to https://www.freedesktop.org/software/systemd/man/systemd.kill.html
Restart=always

[Install]
WantedBy=multi-user.target</code></pre>
<ul>
  <li>Save the file (CTRL-S) and exit (CTRL-X)</li>
  <li>Enable and launch the service:</li>
</ul><pre><code class="language-text-x-trilium-auto">sudo systemctl enable --now -q trilium</code></pre>
<ul>
  <li>You can now open a browser to http://[your-server-hostname]:8080 and you
    should see the Trilium initialization page.</li>
</ul>
<h2>Simple Autoupdate for Server</h2>
<p>Run as the same User Trilium runs</p>
<p>if you run as root please remove 'sudo' from the commands</p>
<p>requires "jq" <code>apt install jq</code>
</p>
<p>It will stop the service above, overwrite everything (i expect no config.ini),
  and start service It also creates a version file in the Trilium directory
  so it updates only with a newer Version</p><pre><code class="language-text-x-trilium-auto">#!/bin/bash

# Configuration
REPO="TriliumNext/Trilium"
PATTERN="TriliumNotes-Server-.*-linux-x64.tar.xz"
DOWNLOAD_DIR="/var/tmp/trilium_download"
OUTPUT_DIR="/opt/trilium"
SERVICE_NAME="trilium"
VERSION_FILE="$OUTPUT_DIR/version.txt"

# Ensure dependencies are installed
command -v curl &gt;/dev/null 2&gt;&amp;1 || { echo "Error: curl is required"; exit 1; }
command -v jq &gt;/dev/null 2&gt;&amp;1 || { echo "Error: jq is required"; exit 1; }
command -v tar &gt;/dev/null 2&gt;&amp;1 || { echo "Error: tar is required"; exit 1; }

# Create download directory
mkdir -p "$DOWNLOAD_DIR" || { echo "Error: Cannot create $DOWNLOAD_DIR"; exit 1; }

# Get the latest release version
LATEST_VERSION=$(curl -sL https://api.github.com/repos/$REPO/releases/latest | jq -r '.tag_name')
if [ -z "$LATEST_VERSION" ]; then
  echo "Error: Could not fetch latest release version"
  exit 1
fi

# Check current installed version (from version.txt or existing tarball)
CURRENT_VERSION=""
if [ -f "$VERSION_FILE" ]; then
  CURRENT_VERSION=$(cat "$VERSION_FILE")
elif [ -f "$DOWNLOAD_DIR/TriliumNotes-Server-$LATEST_VERSION-linux-x64.tar.xz" ]; then
  CURRENT_VERSION="$LATEST_VERSION"
fi

# Compare versions
if [ "$CURRENT_VERSION" = "$LATEST_VERSION" ]; then
  echo "Latest version ($LATEST_VERSION) is already installed"
  exit 0
fi

# Download the latest release
LATEST_URL=$(curl -sL https://api.github.com/repos/$REPO/releases/latest | jq -r ".assets[] | select(.name | test(\"$PATTERN\")) | .browser_download_url")
if [ -z "$LATEST_URL" ]; then
  echo "Error: No asset found matching pattern '$PATTERN'"
  exit 1
fi

FILE_NAME=$(basename "$LATEST_URL")
FILE_PATH="$DOWNLOAD_DIR/$FILE_NAME"

# Download if not already present
if [ -f "$FILE_PATH" ]; then
  echo "Latest release $FILE_NAME already downloaded"
else
  curl -LO --output-dir "$DOWNLOAD_DIR" "$LATEST_URL" || { echo "Error: Download failed"; exit 1; }
  echo "Downloaded $FILE_NAME to $DOWNLOAD_DIR"
fi

# Extract the tarball
EXTRACT_DIR="$DOWNLOAD_DIR/extracted"
mkdir -p "$EXTRACT_DIR"
tar -xJf "$FILE_PATH" -C "$EXTRACT_DIR" || { echo "Error: Extraction failed"; exit 1; }

# Find the extracted directory (e.g., TriliumNotes-Server-0.97.2-linux-x64)
INNER_DIR=$(find "$EXTRACT_DIR" -maxdepth 1 -type d -name "TriliumNotes-Server-*-linux-x64" | head -n 1)
if [ -z "$INNER_DIR" ]; then
  echo "Error: Could not find extracted directory matching TriliumNotes-Server-*-linux-x64"
  exit 1
fi

# Stop the trilium-server service
if systemctl is-active --quiet "$SERVICE_NAME"; then
  echo "Stopping $SERVICE_NAME service..."
  sudo systemctl stop "$SERVICE_NAME" || { echo "Error: Failed to stop $SERVICE_NAME"; exit 1; }
fi

# Copy contents to /opt/trilium, overwriting existing files
echo "Copying contents from $INNER_DIR to $OUTPUT_DIR..."
sudo mkdir -p "$OUTPUT_DIR"
sudo cp -r "$INNER_DIR"/* "$OUTPUT_DIR"/ || { echo "Error: Copy failed"; exit 1; }
echo "$LATEST_VERSION" | sudo tee "$VERSION_FILE" &gt;/dev/null
echo "Files copied to $OUTPUT_DIR"

# Start the trilium-server service
echo "Starting $SERVICE_NAME service..."
sudo systemctl start "$SERVICE_NAME" || { echo "Error: Failed to start $SERVICE_NAME"; exit 1; }

# Clean up
rm -rf "$EXTRACT_DIR"
echo "Cleanup complete. Trilium updated to $LATEST_VERSION."</code></pre>
<h2>Common issues</h2>
<h3>Outdated glibc</h3><pre><code class="language-text-x-trilium-auto">Error: /usr/lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /var/www/virtual/.../node_modules/@mlink/scrypt/build/Release/scrypt.node)
    at Object.Module._extensions..node (module.js:681:18)
    at Module.load (module.js:565:32)
    at tryModuleLoad (module.js:505:12)</code></pre>
<p>If you get an error like this, you need to either upgrade your glibc (typically
  by upgrading to up-to-date distribution version) or use some other <a href="#root/_help_WOcw2SLH6tbX">server installation</a> method.</p>
<h2>TLS</h2>
<p>Don't forget to <a href="#root/_help_l2VkvOwUNfZj">configure TLS</a>, which
  is required for secure usage!</p>